using SaToken.SaToken.Session;

namespace SaToken.SaToken.dao;

/// <summary>
/// Sa-Token 持久层接口
/// 
/// <para>
/// 此接口的不同实现类可将数据存储至不同位置，如：内存Map、Redis 等等。
/// 如果你要自定义数据存储策略，也需通过实现此接口来完成。
/// </para>
/// </summary>
public interface ISaTokenDao
{
    /// <summary>
    /// 常量，表示一个 key 永不过期 （在一个 key 被标注为永远不过期时返回此值）
    /// </summary>
    public static readonly long NeverExpire = -1;

    /// <summary>
    /// 常量，表示系统中不存在这个缓存（在对不存在的 key 获取剩余存活时间时返回此值）
    /// </summary>
    public static readonly long NotValueExpire = -2;


    // --------------------- 字符串读写 ---------------------

    /// <summary>
    /// 获取 value，如无返空
    /// </summary>
    /// <param name="key">键名称</param>
    /// <returns>value</returns>
    string Get(string key);

    /// <summary>
    /// 写入 value，并设定存活时间（单位: 秒）
    /// </summary>
    /// <param name="key">键名称</param>
    /// <param name="value">值</param>
    /// <param name="timeout">数据有效期（值大于0时限时存储，值=-1时永久存储，值=0或小于-2时不存储）</param>
    void Set(string key, string value, long timeout);

    /// <summary>
    /// 更新 value （过期时间不变）
    /// </summary>
    /// <param name="key">键名称</param>
    /// <param name="value">值</param>
    void Update(string key, string value);

    /// <summary>
    /// 删除 value
    /// </summary>
    /// <param name="key">键名称</param>
    void Delete(string key);

    /// <summary>
    /// 获取 value 的剩余存活时间（单位: 秒）
    /// </summary>
    /// <param name="key">指定 key</param>
    /// <returns>这个 key 的剩余存活时间</returns>
    long GetTimeout(string key);

    /// <summary>
    /// 修改 value 的剩余存活时间（单位: 秒）
    /// </summary>
    /// <param name="key">指定 key</param>
    /// <param name="timeout">过期时间（单位: 秒）</param>
    void UpdateTimeout(string key, long timeout);


    // --------------------- 对象读写 ---------------------

    /// <summary>
    /// 获取 Object，如无返空
    /// </summary>
    /// <param name="key">键名称</param>
    /// <returns>object</returns>
    object GetObject(string key);

    /// <summary>
    /// 获取 Object (指定反序列化类型)，如无返空
    /// </summary>
    /// <typeparam name="T">对象类型</typeparam>
    /// <param name="key">键名称</param>
    /// <returns>object</returns>
    T GetObject<T>(string key);

    /// <summary>
    /// 写入 Object，并设定存活时间 （单位: 秒）
    /// </summary>
    /// <param name="key">键名称</param>
    /// <param name="obj">值</param>
    /// <param name="timeout">存活时间（值大于0时限时存储，值=-1时永久存储，值=0或小于-2时不存储）</param>
    void SetObject(string key, object obj, long timeout);

    /// <summary>
    /// 更新 Object （过期时间不变）
    /// </summary>
    /// <param name="key">键名称</param>
    /// <param name="obj">值</param>
    void UpdateObject(string key, object obj);

    /// <summary>
    /// 删除 Object
    /// </summary>
    /// <param name="key">键名称</param>
    void DeleteObject(string key);

    /// <summary>
    /// 获取 Object 的剩余存活时间 （单位: 秒）
    /// </summary>
    /// <param name="key">指定 key</param>
    /// <returns>这个 key 的剩余存活时间</returns>
    long GetObjectTimeout(string key);

    /// <summary>
    /// 修改 Object 的剩余存活时间（单位: 秒）
    /// </summary>
    /// <param name="key">指定 key</param>
    /// <param name="timeout">剩余存活时间</param>
    void UpdateObjectTimeout(string key, long timeout);


    // --------------------- SaSession 读写 （默认复用 Object 读写方法） ---------------------

    /// <summary>
    /// 获取 SaSession，如无返空
    /// </summary>
    /// <param name="sessionId">sessionId</param>
    /// <returns>SaSession</returns>
    SaSession GetSession(string sessionId);

    /// <summary>
    /// 写入 SaSession，并设定存活时间（单位: 秒）
    /// </summary>
    /// <param name="session">要保存的 SaSession 对象</param>
    /// <param name="timeout">过期时间（单位: 秒）</param>
    void SetSession(SaSession session, long timeout);

    /// <summary>
    /// 更新 SaSession
    /// </summary>
    /// <param name="session">要更新的 SaSession 对象</param>
    void UpdateSession(SaSession session);

    /// <summary>
    /// 删除 SaSession
    /// </summary>
    /// <param name="sessionId">sessionId</param>
    void DeleteSession(string sessionId);

    /// <summary>
    /// 获取 SaSession 剩余存活时间（单位: 秒）
    /// </summary>
    /// <param name="sessionId">指定 SaSession</param>
    /// <returns>这个 SaSession 的剩余存活时间</returns>
    long GetSessionTimeout(string sessionId);

    /// <summary>
    /// 修改 SaSession 剩余存活时间（单位: 秒）
    /// </summary>
    /// <param name="sessionId">指定 SaSession</param>
    /// <param name="timeout">剩余存活时间</param>
    void UpdateSessionTimeout(string sessionId, long timeout);


    // --------------------- 会话管理 ---------------------

    /// <summary>
    /// 搜索数据
    /// </summary>
    /// <param name="prefix">前缀</param>
    /// <param name="keyword">关键字</param>
    /// <param name="start">开始处索引</param>
    /// <param name="size">获取数量  (-1代表从 start 处一直取到末尾)</param>
    /// <param name="sortType">排序类型（true=正序，false=反序）</param>
    /// <returns>查询到的数据集合</returns>
    List<string> SearchData(string prefix, string keyword, int start, int size, bool sortType);


    // --------------------- 生命周期 ---------------------

    /// <summary>
    /// 当此 SaTokenDao 实例被装载时触发
    /// </summary>
    void Init()
    {
    }

    /// <summary>
    /// 当此 SaTokenDao 实例被卸载时触发
    /// </summary>
    void Destroy()
    {
    }
}